package algorithm.middle;

import pojo.ListNode;

/**
 * @BelongsProject: LeetCode
 * @BelongsPackage: algorithm.middle
 * @Author: 江岸
 * @CreateTime: 2021-03-27 14:13
 * @Description: 61. 旋转链表
 * 给你一个链表的头节点 head ，旋转链表，将链表每个节点向右移动 k 个位置。
 * 输入：head = [1,2,3,4,5], k = 2
 * 输出：[4,5,1,2,3]
 * 输入：head = [0,1,2], k = 4
 * 输出：[2,0,1]
 */
public class RotateRight61 {

    //链表
    public ListNode rotateRight(ListNode head, int k) {
        if (head==null || head.next==null){
            return head;
        }
        int len = 0;
        ListNode cur = head;
        while (cur!=null){
            len++;
            cur = cur.next;
        }
        k = k%len;
        if (k==0) return head;
        int num = len -k;
        cur = head;
        for (int i=1;i<num;i++){
            cur = cur.next;
        }
        ListNode newHead = cur.next;
        cur.next = null;
        ListNode temp = newHead;
        while (temp.next!=null){
            temp=temp.next;
        }
        temp.next = head;
        return newHead;
    }

    /**
     *
     * 记给定链表的长度为 nnn，注意到当向右移动的次数 k≥nk \geq nk≥n 时，我们仅需要向右移动 k mod nk \bmod nkmodn 次即可。因为每 nnn 次移动都会让链表变为原状。这样我们可以知道，新链表的最后一个节点为原链表的第 (n−1)−(k mod n)(n - 1) - (k \bmod n)(n−1)−(kmodn) 个节点（从 000 开始计数）。
     *
     * 这样，我们可以先将给定的链表连接成环，然后将指定位置断开。
     *
     * 具体代码中，我们首先计算出链表的长度 nnn，并找到该链表的末尾节点，将其与头节点相连。这样就得到了闭合为环的链表。然后我们找到新链表的最后一个节点（即原链表的第 (n−1)−(k mod n)(n - 1) - (k \bmod n)(n−1)−(kmodn) 个节点），将当前闭合为环的链表断开，即可得到我们所需要的结果。
     *
     * 特别地，当链表长度不大于 111，或者 kkk 为 nnn 的倍数时，新链表将与原链表相同，我们无需进行任何处理。
     *
     * 作者：LeetCode-Solution
     * 链接：https://leetcode-cn.com/problems/rotate-list/solution/xuan-zhuan-lian-biao-by-leetcode-solutio-woq1/
     * 来源：力扣（LeetCode）
     * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
     */
    public ListNode 官方解法(ListNode head, int k) {
        if (k == 0 || head == null || head.next == null) {
            return head;
        }
        int n = 1;
        ListNode iter = head;
        while (iter.next != null) {
            iter = iter.next;
            n++;
        }
        int add = n - k % n;
        if (add == n) {
            return head;
        }
        iter.next = head;
        while (add-- > 0) {
            iter = iter.next;
        }
        ListNode ret = iter.next;
        iter.next = null;
        return ret;
    }


}
